﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

namespace Nirvana
{
   
    /// <summary>
    /// 动画资源导入检测规则脚本，一般是UI动画，特效动画等，不是FBX导入进来的动画
    /// 注意：
    ///     规则文件必须存放在资源的父目录或同一级目录下。便于不同资源模块的管理。
    /// </summary>
    [CreateAssetMenu(fileName = "@AnimationImportRule", menuName = "Nirvana/Asset/AnimationImportRule")]
    public class AnimationImportRule : ScriptableObject
    {
        [Tooltip("曲线精度压缩f3")]
        [SerializeField]
        private BoolVariate floatOptimize;
        [Tooltip("曲线剔除scale信息,模型动画使用，UI动画不要使用")]
        [SerializeField]
        private BoolVariate scaleOptimize;
        [Tooltip("剔除接近0的曲线,模型动画使用,UI动画不要清除，会清除Alpha等值的误判")]
        [SerializeField]
        private BoolVariate clearEmptyCurve;

        /// <summary>
        /// 返回当前配置脚本的存放目录
        /// </summary>
        /// <returns></returns>
        public string GetDirectorName()
        {
            string assetpath = AssetDatabase.GetAssetPath(this);
            return Path.GetDirectoryName(assetpath);
        }


        public void MathAnimation()
        {
            string findpath = GetDirectorName();
            string[] allRules = AssetDatabase.FindAssets("t:AnimationClip",new string[] { findpath });
            foreach (var p in allRules)
            {
                string path = AssetDatabase.GUIDToAssetPath(p);
                if (path.EndsWith(".anim"))
                {
                    Debug.LogFormat("<color=green>Path:{0}</color>", path);
                    MatchAnimation(AssetDatabase.LoadAssetAtPath<AnimationClip>(path));
                }
            }

        }

        private void MatchAnimation(AnimationClip theAnimation)
        {
            //去除scale曲线
            if (scaleOptimize.IsHasValue() && scaleOptimize.GetValue())
            {
                foreach (EditorCurveBinding theCurveBinding in AnimationUtility.GetCurveBindings(theAnimation))
                {
                    string name = theCurveBinding.propertyName.ToLower();
                    if (name.Contains("scale"))
                    {
                        AnimationUtility.SetEditorCurve(theAnimation, theCurveBinding, null);
                    }
                }
            }
            //浮点数精度压缩到f3
            if (floatOptimize.IsHasValue() && floatOptimize.GetValue())
            {
                EditorCurveBinding[] curveBindings = AnimationUtility.GetCurveBindings(theAnimation);
                Keyframe keyframe;
                Keyframe[] keyFrames;
                foreach (var curveBinding in curveBindings)
                {
                    AnimationCurve animationCurve = AnimationUtility.GetEditorCurve(theAnimation, curveBinding);
                    if (animationCurve == null || animationCurve.keys == null)
                    {
                        continue;
                    }
                    // 要移除的帧
                    List<int> removeIdxs = new List<int>();
                    keyFrames = animationCurve.keys;
                    for (int i = 0; i < keyFrames.Length; i++)
                    {
                        keyframe = keyFrames[i];
                        keyframe.value = float.Parse(keyframe.value.ToString("f3"));
                        keyframe.inTangent = float.Parse(keyframe.inTangent.ToString("f3"));
                        keyframe.outTangent = float.Parse(keyframe.outTangent.ToString("f3"));
                        keyframe.inWeight = float.Parse(keyframe.inWeight.ToString("f3"));
                        keyframe.outWeight = float.Parse(keyframe.outWeight.ToString("f3"));
                        keyFrames[i] = keyframe;

                        if(clearEmptyCurve.IsHasValue() && clearEmptyCurve.GetValue())
                        {
                            //恒量 (变化小的关键帧) 比较曲线的输入和输出变化，如果是基本稳定，即为常量
                            // 是否是异常量关键帧或者无限接近0
                            if ((float.IsInfinity(keyframe.inTangent) && float.IsInfinity(keyframe.outTangent))
                                || (Mathf.Abs(keyframe.inTangent) <= float.Epsilon && Mathf.Abs(keyframe.outTangent) <= float.Epsilon))
                            {
                                removeIdxs.Add(i);
                            }
                        }

                    }
                    animationCurve.keys = keyFrames;
                    //theAnimation.SetCurve(curveBinding.path, curveBinding.type, curveBinding.propertyName, animationCurve);
                    // 移除
                    for (int r = removeIdxs.Count - 1; r >= 0; --r)
                    {
                        animationCurve.RemoveKey(removeIdxs[r]);
                    }
                    // 如果curve的关键帧已经没有了，直接移除空的curve
                    if (animationCurve.length == 0)
                    {
                        AnimationUtility.SetEditorCurve(theAnimation, curveBinding, null);
                    }
                    else
                    {
                        theAnimation.SetCurve(curveBinding.path, curveBinding.type, curveBinding.propertyName, animationCurve);
                    }

                }
            }

            EditorUtility.SetDirty(theAnimation);
            // 重新保存
            AssetDatabase.SaveAssets();
        }
    }
}

